package com.sunwayworld.basemodule.rm.equipment.repair.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sunwayworld.basemodule.business.report.bean.LimsReportBean;
import com.sunwayworld.basemodule.rm.equipment.bean.LimsEquipmentBean;
import com.sunwayworld.basemodule.rm.equipment.dao.LimsEquipmentDao;
import com.sunwayworld.basemodule.rm.equipment.service.LimsEquipmentService;
import com.sunwayworld.framework.audit.aunnotation.Audit;
import com.sunwayworld.framework.context.LocalContextHelper;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.restful.data.RestValidationResultBean;
import com.sunwayworld.framework.support.auditable.bean.CoreBpmnParameterDTO;
import com.sunwayworld.framework.utils.CollectionUtils;
import com.sunwayworld.framework.utils.ObjectUtils;
import com.sunwayworld.module.sys.bpmn.bean.CoreBpmnInstanceStatusDTO;
import com.sunwayworld.module.sys.bpmn.engine.CoreBpmnRuntimeService;
import com.sunwayworld.module.sys.bpmn.engine.CoreBpmnRuntimeSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.sunwayworld.framework.at.annotation.AuditTrailType;
import com.sunwayworld.framework.at.annotation.AuditTrailEntry;
import com.sunwayworld.framework.spring.annotation.GikamBean;

import com.sunwayworld.basemodule.rm.equipment.repair.dao.LimsEquiptRepairDao;
import com.sunwayworld.basemodule.rm.equipment.repair.bean.LimsEquiptRepairBean;
import com.sunwayworld.basemodule.rm.equipment.repair.service.LimsEquiptRepairService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;
import org.thymeleaf.expression.Ids;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Repository
@GikamBean
public class LimsEquiptRepairServiceImpl implements LimsEquiptRepairService {

    @Autowired
    private LimsEquiptRepairDao limsEquiptRepairDao;

    @Autowired
    private LimsEquipmentService equiptService;

    @Autowired
    private LimsEquipmentDao limsEquiptDao;

    @Override
    @SuppressWarnings("unchecked")
    public LimsEquiptRepairDao getDao() {
        return limsEquiptRepairDao;
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.INSERT)
    public Long insert(RestJsonWrapperBean jsonWrapper) {
        LimsEquiptRepairBean limsEquiptRepair = jsonWrapper.parseUnique(LimsEquiptRepairBean.class);
        limsEquiptRepair.setId(ApplicationContextHelper.getNextIdentity());
        limsEquiptRepair.setApplicant(LocalContextHelper.getLoginUserName());
        limsEquiptRepair.setApplicantId(LocalContextHelper.getLoginUserId());
        limsEquiptRepair.setApplyDept(LocalContextHelper.getLoginOrgName());
        limsEquiptRepair.setApplyDeptId(LocalContextHelper.getLoginOrgId());
        limsEquiptRepair.setApplyDate(LocalDateTime.now());
        getDao().insert(limsEquiptRepair);
        return limsEquiptRepair.getId();
    }

    public RestValidationResultBean validateChineseValue(RestJsonWrapperBean wrapper, String columnName, String columnValue) {
        RestValidationResultBean restValidationResultBean = new RestValidationResultBean(true);

        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(columnValue);
        boolean b = m.find();

        if(b){
            restValidationResultBean.setMessage("PLEASE.INPUT.NOT.CHINESE");
            restValidationResultBean.setValid(false);
            return restValidationResultBean;
        }
        return restValidationResultBean;
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.UPDATE)
    public void updateEquiptStatus(RestJsonWrapperBean wrapper) {
        String bpmn_statusCode = wrapper.getParamValue("bpmn_statusCode");
        if ("Affirm".equals(bpmn_statusCode)){
            JSONObject p = (JSONObject) JSON.parseObject(wrapper.getRequestJson()).get("p");
            Object ids1 =p.get("ids");
            String s1 = JSONObject.toJSONString(ids1);
            List<Long> longs = JSONArray.parseArray(s1, Long.class);
            List<LimsEquiptRepairBean> limsEquiptRepairBeans = this.getDao().selectListByIds(longs);
            List<Long> collect = limsEquiptRepairBeans.stream().map(LimsEquiptRepairBean::getEquiptId).collect(Collectors.toList());
            List<LimsEquipmentBean> limsEquiptBeans = limsEquiptDao.selectListByIds(collect);
            for (LimsEquipmentBean limsEquiptBean : limsEquiptBeans) {
                limsEquiptBean.setEquipState("normal");
            }
            limsEquiptDao.update(limsEquiptBeans, "equipState");
        }
    }

    @Transactional
    @AuditTrailEntry(AuditTrailType.PROCESS_COMPLETE)
    @Audit("AUDIT.PROCESS_COMPLETE")
    public List<CoreBpmnInstanceStatusDTO<Long>> completeTask(RestJsonWrapperBean wrapper) {
        List<LimsEquiptRepairBean> itemList = wrapper.parse(this.getDao().getType());
        if (itemList.isEmpty()) {
            return CollectionUtils.emptyList();
        } else {
            this.checkAndUpdateVersion(itemList);
            CoreBpmnRuntimeService runtimeService = (CoreBpmnRuntimeService)ApplicationContextHelper.getBean(CoreBpmnRuntimeService.class);
            List<Long> itemIdList = (List)itemList.stream().map((i) -> {
                return (Serializable)i.getId();
            }).collect(Collectors.toList());
            List<LimsEquiptRepairBean> selectItemList = this.getBpmnVarsItemList(itemIdList);


            List<CoreBpmnRuntimeSource<LimsEquiptRepairBean, Long>> runtimeSourceList =
                    this.parseAuditableRuntimeSource(itemIdList, CoreBpmnParameterDTO.of(wrapper), this.getBpmnVars(wrapper, selectItemList));
            List<CoreBpmnInstanceStatusDTO<Long>> instanceStatusList = runtimeService.completeTask(runtimeSourceList);
            //添加校验
            if(instanceStatusList.get(0).getStatusCode().equals("Implement")){
                for(LimsEquiptRepairBean repairBean:selectItemList){
                    if(repairBean.getRepairMeasure()==null){
                        throw new InvalidDataException("故障维修措施不能为空！");
                    }
                    if(repairBean.getFinishDate()==null){
                        throw new InvalidDataException("完成时间不能为空！");
                    }
                    if(repairBean.getStopHours()==null){
                        throw new InvalidDataException("停机时长不能为空！");
                    }
                    if(repairBean.getRepairPerson()==null){
                        throw new InvalidDataException("维修人员不能为空！");
                    }
                    if(repairBean.getRepairCost()==null){
                        throw new InvalidDataException("维修费用不能为空！");
                    }
                }
            }
            this.autoPass(runtimeSourceList, instanceStatusList);
            // 获取设备维修数据
            List<LimsEquiptRepairBean> equiptRepairs = selectListByFilter(SearchFilter.instance()
                .match("ID", itemIdList).filter(MatchPattern.OR)
                .match("PROCESSSTATUS", "done").filter(MatchPattern.SEQ));
            if (!CollectionUtils.isEmpty(equiptRepairs)) {
                // 获取设备IDS
                List<Long> equiptIds = equiptRepairs.stream().map(LimsEquiptRepairBean::getEquiptId).collect(Collectors.toList());
                // 查询设备维修数据（完成状态）
                List<LimsEquipmentBean> equipts = equiptService.selectListByIds(equiptIds);
                equipts.forEach(u->u.setEquipState("normal"));
                equiptService.getDao().update(equipts, "equipState");
            }
            // 将设备状态修改为在用
            return instanceStatusList;
        }
    }

}
